package main

import (
	"fmt"
	"runtime"
	"os"
	"net"
	"./protocol"
)

const SERVER = "127.0.0.1:7981"

var (
	Clients map[int]Client = make(map[int]Client)
)

type Client struct {
	Index 	int
	conn 	net.Conn
}

func (client *Client) address() string {
	return client.conn.RemoteAddr().String()
}

func (client *Client) OnConnect() {
	fmt.Println("add connect, from: ", client.address(), ", index: ", client.Index)
}

func (client *Client) OnClose() {
	fmt.Println("delete connect, from: ", client.address(), ", index:", client.Index)
	client.conn.Close()
	delete(Clients, client.Index)
}

func (client *Client) OnReceive(data string) {
	fmt.Println("client from: ", client.address() ,", message: ", data, ", index:", client.Index)

	client.Send(data)
}

func (client *Client) Send(message string)  {
	client.conn.Write(protocol.Packet([]byte(message)))
}

func main()  {
	runtime.GOMAXPROCS(runtime.NumCPU())

	fmt.Println("server start, listen:", SERVER)

	tcp, err := net.ResolveTCPAddr("tcp4", SERVER)
	if err != nil {
		fmt.Println("error:", err.Error())
		os.Exit(1)
	}

	listener, err := net.ListenTCP("tcp", tcp)
	if err != nil {
		fmt.Println("error:", err.Error())
		os.Exit(1)
	}

	index := 0
	for {
		conn, err := listener.Accept()
		if err != nil {
			fmt.Println("listen error: ", err.Error())
			continue
		}

		index++
		go HandleClient(conn, index)
	}
}

func NewClient(conn net.Conn, index int) Client {
	client := Client{index, conn}
	Clients[index] = client
	client.OnConnect()
	return client
}

func HandleClient(conn net.Conn, index int) {
	client := NewClient(conn, index)
	fmt.Println("client index:", client.Index)

	defer client.OnClose()

	protocol.Read(client.conn, client.OnReceive)
}